package com.itheima.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.dto.DishDto;
import com.itheima.dto.SetmealDto;
import com.itheima.mapper.*;
import com.itheima.pojo.*;
import com.itheima.result.R;
import com.itheima.service.SetmealDtoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.zip.Inflater;

/**
 * @Author: 斌
 * @DateTime: 2023年02月07日  00:09:20
 * @Description: com.itheima.service.Impl
 * @Version: 1.0
 */
@Slf4j
@Service
public class SetmealDtoServiceImpl extends ServiceImpl<SetmealDao, Setmeal> implements SetmealDtoService {
    @Autowired
    private SetmealDao setmealDao;

    @Autowired
    private DishFlavorDao dishFlavorDao;
    @Autowired
    private DishDao dishDao;

    @Autowired
    private CategoryDao categoryDao;

    @Autowired
    private setmealDishDao setmealDishDao;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 分页查询
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public R SetmealPage(Integer page, Integer pageSize,String name) {
        Page<Setmeal> mealPage = new Page<>(page,pageSize);
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotEmpty(name),Setmeal::getName,name);
        Page<Setmeal> setmealPage = setmealDao.selectPage(mealPage, queryWrapper);

        Page<SetmealDto> setmealDtoPage = new Page<>(page,pageSize);

        //这里是获取总条数
        BeanUtils.copyProperties(setmealPage,setmealDtoPage,"records");
        List<SetmealDto> setmealDtos = setmealPage.getRecords().stream().map(setmeal -> {
            Long categoryId = setmeal.getCategoryId();
            Category category = categoryDao.selectById(categoryId);
            SetmealDto setmealDto = new SetmealDto();
            setmealDto.setCategoryName(category.getName());
            //这里是把setmeal的数据腾到setmealDto中，不然他的数据有缺失
            BeanUtils.copyProperties(setmeal,setmealDto);
            return setmealDto;
        }).collect(Collectors.toList());
        log.info("返回给前端主要数据:{}",setmealDtos);
        //这里是把缺失的records补上
        setmealDtoPage.setRecords(setmealDtos);
        return R.success(setmealDtoPage);
    }

    @Override
    public R saveSetMeal(SetmealDto setmealDto) {
        //增删改操作把之前存Redis的数据删掉，保证查的时候数据和MySQL是同步的
        Set keys = redisTemplate.keys("setmeal_*");
        redisTemplate.delete(keys);

        if (setmealDto != null){
            int setmealResult = setmealDao.insert(setmealDto);
            List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
            int setmealDishResult = 0;
            if (setmealDishes.size() != 0){
                for (SetmealDish setmealDish : setmealDishes) {
                    Long setmealId = setmealDto.getId();
                    setmealDish.setSetmealId(setmealId);
                     setmealDishResult = setmealDishDao.insert(setmealDish);
                }
                if (setmealResult >0 && setmealDishResult > 0){
                    return R.success("添加套餐成功");
                }else {
                    return R.error("添加套餐失败");
                }
            }

        }
        return R.error("数据异常");
    }

    @Override
    public R querySetmeal(Long id) {
        //查询出id对应的套餐
        Setmeal setmeal = setmealDao.selectById(id);
        //查出对应的菜品类
        Long categoryId = setmeal.getCategoryId();
        Category category = categoryDao.selectById(categoryId);
        //菜品类名
        String name = category.getName();
        //根据id查出所属该套餐的菜品集合
        LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper = new LambdaQueryWrapper<>();
        setmealDishLambdaQueryWrapper.eq(id != null,SetmealDish::getSetmealId,id);
        List<SetmealDish> setmealDishes = setmealDishDao.selectList(setmealDishLambdaQueryWrapper);
        //进行数据封装，返回给前端
        SetmealDto setmealDto = new SetmealDto();
        setmealDto.setCategoryName(name);
        setmealDto.setSetmealDishes(setmealDishes);
        BeanUtils.copyProperties(setmeal,setmealDto);


        return R.success(setmealDto);
    }

    @Override
    public R updateSetmeal(SetmealDto setmealDto) {
        //增删改操作把之前存Redis的数据删掉，保证查的时候数据和MySQL是同步的
        Set keys = redisTemplate.keys("setmeal_*");
        redisTemplate.delete(keys);

        //总思路，先删后增。修改---》执行的是删除新增的逻辑
        //获取套餐id，将套餐进行物理删除
        Long id = setmealDto.getId();
        int deleteSetmealResult = setmealDao.deleteById(id);
        //获取所有的菜品信息，进行批量根据所属套餐id逻辑删除
        LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper = new LambdaQueryWrapper<>();
        setmealDishLambdaQueryWrapper.eq(SetmealDish::getSetmealId,id);
        int deleteSetmealDishResult = setmealDishDao.delete(setmealDishLambdaQueryWrapper);
        int insertSetmealResult = 0;
        int insertSetmealDishResult = 0;
        //判断，删除成功，进行新增
        if (deleteSetmealResult > 0 && deleteSetmealDishResult >0){
            //对套餐表进行新增
             insertSetmealResult = setmealDao.insert(setmealDto);
            //现将菜品所有id进行置空，再进行添加，因为进行的逻辑删除，原菜品id还在
            List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
            for (SetmealDish setmealDish : setmealDishes) {
                setmealDish.setId(null);
                setmealDish.setSetmealId(setmealDto.getId());
                 insertSetmealDishResult = setmealDishDao.insert(setmealDish);
            }
            //返回添加结果
        }


        return (insertSetmealResult > 0 && insertSetmealDishResult > 0) ? R.success("修改成功") : R.error("修改失败");
    }

    @Override
    public R updateSetmealStatus(Integer status,List<Long> ids) {
        //增删改操作把之前存Redis的数据删掉，保证查的时候数据和MySQL是同步的
        Set keys = redisTemplate.keys("setmeal_*");
        redisTemplate.delete(keys);


        LambdaUpdateWrapper<Setmeal> setmealLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        if (status == 0){

            setmealLambdaUpdateWrapper.set(Setmeal::getStatus,status).in(Setmeal::getId,ids);
            int updateStatusResult = setmealDao.update(null, setmealLambdaUpdateWrapper);
            return updateStatusResult > 0 ? R.success("状态更新成功") : R.error("更新失败");
        }else {
            setmealLambdaUpdateWrapper.set(Setmeal::getStatus,status).in(Setmeal::getId,ids);
            int updateStatusResult = setmealDao.update(null, setmealLambdaUpdateWrapper);
            return updateStatusResult > 0 ? R.success("状态更新成功") : R.error("更新失败");
        }

    }

    @Override
    public R deleteSetmeal(List<Long> ids) {

        //增删改操作把之前存Redis的数据删掉，保证查的时候数据和MySQL是同步的
        Set keys = redisTemplate.keys("setmeal_*");
        redisTemplate.delete(keys);

        //总思路，先查询当前套餐状态，启用--》禁止删除 ，停用--》可以删除
        //select count(*) from setmeal where status = 1 and id in (?,?,?)
        LambdaQueryWrapper<Setmeal> setmealLambdaQueryWrapper = new LambdaQueryWrapper<>();
        setmealLambdaQueryWrapper.eq(Setmeal::getStatus,0).in(Setmeal::getId,ids);
        Integer selectCount = setmealDao.selectCount(setmealLambdaQueryWrapper);
        int deleteSetmealResult = 0;
        int deleteSetmealDishResult = 0;
        //判断
        if (selectCount > 0 ){
            //删除套餐 delete from setmeal where id in (?,?,?)
            for (Long id : ids) {
                 deleteSetmealResult = setmealDao.deleteById(id);
                LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper = new LambdaQueryWrapper<>();
                LambdaQueryWrapper<SetmealDish> wrapper = setmealDishLambdaQueryWrapper.eq(SetmealDish::getSetmealId, id);
                //删除所属套餐下的菜品，循环删除，delete from setmeal_dish where setmeal_id = ?
                 deleteSetmealDishResult = setmealDishDao.delete(wrapper);
            }

        }

        //返回结果
        return (deleteSetmealResult > 0 && deleteSetmealDishResult > 0) ? R.success("删除成功") : R.error("售卖中的套餐不能删除");
    }

    /**
     *
     * @param setmealDto
     * @return
     */
    @Override
    public R setmealList(SetmealDto setmealDto) {
        //判断
        String setmealRedisKey = "setmeal_" +setmealDto.getCategoryId();
        List<SetmealDto> setmealDtos = (List<SetmealDto>) redisTemplate.opsForValue().get(setmealRedisKey);
        if (setmealDtos != null){
            return R.success(setmealDtos);
        }
        //查询套餐
        LambdaQueryWrapper<Setmeal> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(setmealDto.getCategoryId() !=null,Setmeal::getCategoryId,setmealDto.getCategoryId())
                .eq(setmealDto.getStatus() !=null,Setmeal::getStatus,setmealDto.getStatus());
        List<Setmeal> setmeals = setmealDao.selectList(wrapper);
        //这里的套餐展示具体的菜品数据，套餐菜品是商家后台选好的，不是顾客自己选的
         List<SetmealDto> setmealDishList = new ArrayList<SetmealDto>();
        for (Setmeal setmeal : setmeals) {
            SetmealDto dto = new SetmealDto();
            //查询套餐下菜品
            LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(setmeal.getId() !=null,SetmealDish::getSetmealId,setmeal.getId());
            List<SetmealDish> setmealDishes = setmealDishDao.selectList(queryWrapper);
            setmealDto.setSetmealDishes(setmealDishes);
            BeanUtils.copyProperties(setmeal,dto);
           setmealDishList.add(dto);
        }
        log.info("套餐数据：{}",setmeals);
        //存入
        redisTemplate.opsForValue().set(setmealRedisKey,setmealDishList);

        return R.success(setmealDishList);
    }

    @Override
    public R querySetmealDish(Long id) {


        //从前端传来套餐id
        //根据套餐id查询归属于该套的菜品集合
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(id !=null,SetmealDish::getSetmealId,id);
        List<SetmealDish> setmealDishList = setmealDishDao.selectList(queryWrapper);
        //遍历集合查出菜品口味
        List<DishDto> dishDtoList = setmealDishList.stream().map(setmealDish -> {
            //setmealDish代表套餐中的每到菜品
            //dto是要封装的对象
            DishDto dishDto = new DishDto();
            //根据菜品id，查出对应的口味信息
            LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(setmealDish.getDishId() != null, DishFlavor::getDishId, setmealDish.getDishId());
            LambdaQueryWrapper<Dish> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(setmealDish.getDishId() != null, Dish::getId, setmealDish.getDishId());
            Dish dish = dishDao.selectOne(lambdaQueryWrapper);
            List<DishFlavor> dishFlavors = dishFlavorDao.selectList(wrapper);
            dishDto.setFlavors(dishFlavors);
            dishDto.setCopies(setmealDish.getCopies());
            BeanUtils.copyProperties(dish, dishDto);
            return dishDto;
        }).collect(Collectors.toList());


        //这里要返回菜品dto数据
        return R.success(dishDtoList);
    }
}
